#include "mosquitto.h"
#include "stdio.h"
#include "string.h"
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>

#define ARR_SIZE(a)  (sizeof(a)/sizeof(a[0]))

#define MQTT_PORT   1883

struct mosquitto *mosq = NULL;

static const char *topic[] = {
    "led",
    "fan",
    "curtain",
};

static int mosquitoto_subscribe_topic(const char *topic, int mid, int qos)
{
    return mosquitto_subscribe(mosq, &mid, topic, qos);
}

static void mosq_on_connect_callback(struct mosquitto *mosq, void *obj, int mid)
{
    int ret = 0;

    for (int i = 0; i < ARR_SIZE(topic); i++)
    {
        if ((ret = mosquitoto_subscribe_topic(topic[i], i, 2)) == MOSQ_ERR_SUCCESS)           //订阅主题
        {
            printf("subscribe success\n");
        }
        else
        {
            fprintf(stderr, "subscribe failed %d\n", ret);
        }
    }

    if ((ret = mosquitoto_subscribe_topic("aaa", 0, 2)) == MOSQ_ERR_SUCCESS)           //订阅主题
    {
        printf("subscribe success\n");
    }
    else
    {
        fprintf(stderr, "subscribe failed %d\n", ret);
    }
   
}

static void mosq_on_publish_callback(struct mosquitto *mosq, void *obj, int mid)
{

}

static void mosq_on_subscribe_callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos)
{

}

void mosq_on_message_get_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
{
    if (message->payloadlen > 0)
    {
        printf("topic : %s, message : %s\r\n", message->topic, (char *)message->payload);
    }
}

static void mosquitto_mqtt_init(char *host, int port, int keepalive)
{
    mosquitto_lib_init();     //初始化mosquitto库

    mosq = mosquitto_new(NULL, true, NULL);     //创建一个mosquitto实例

    if (mosq == NULL)
    {
        mosquitto_destroy(mosq);    //连接失败销毁
        mosquitto_lib_cleanup();
        printf("create mosquitto obj failed\r\n");   
        exit(1);
    }

    mosquitto_connect_callback_set(mosq, mosq_on_connect_callback);       //设置连接成功回到函数
    mosquitto_publish_callback_set(mosq, mosq_on_publish_callback);       //设置发布成功回调函数
    mosquitto_subscribe_callback_set(mosq, mosq_on_subscribe_callback);   //设置订阅请求成功回调函数
    mosquitto_message_callback_set(mosq, mosq_on_message_get_callback);   //设置消息接收成功回调

    int retries = 0;
    //return val MOSQ_ERR_SUCCESS
    while (mosquitto_connect(mosq, host, port, keepalive) != MOSQ_ERR_SUCCESS && retries < 5)   //如果连接失败，尝试重复连接5次
    {
        retries++;
    }

    if (retries >= 5)
    {
        printf("connect mqtt broker failed\n");
        mosquitto_destroy(mosq);    //连接失败销毁
        mosquitto_lib_cleanup();
        exit(1);
    }
    printf("connect mqtt broker\r\n");
}


int main(int argc, char **argv)
{
    if (argc != 2)
    {
        printf("Usage: %s <host_ip>\r\n", argv[0]);
        exit(1);
    }

    char *host = argv[1];
    int port = MQTT_PORT;
    int keepalive = 30;

    mosquitto_mqtt_init(host, port, keepalive);
   
    // mosquitto_loop_forever(mosq, -1000, 1);

      
    if (mosquitto_loop_start(mosq) != MOSQ_ERR_SUCCESS)
    {
        printf("failed to Call this once to start a new thread to process network traffic\n");
        mosquitto_destroy(mosq);      //连接失败销毁
        mosquitto_lib_cleanup();
        exit(1);
    }

    while (1)
    {
        // mosquitto_loop(mosq, -1, 1);
        // printf("subscribe client running\n");
        sleep(2);
    }
 
    mosquitto_destroy(mosq);      //连接失败销毁
    mosquitto_lib_cleanup();
    return 0;
}